#ifndef __LINUX_SOCKET_H__
#define __LINUX_SOCKET_H__

#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "linux_types.h"

typedef u_int ftp_scoket;

#define INVALID_SOCKET  (ftp_scoket)(~0)
#define SOCKET_ERROR            (-1)
#ifndef INADDR_NONE
#define INADDR_NONE             0xffffffff
#endif

#define FD_READ_BIT      0
#define FD_READ          (1 << FD_READ_BIT)
#define FD_WRITE_BIT     1
#define FD_WRITE         (1 << FD_WRITE_BIT)
#define FD_OOB_BIT       2
#define FD_OOB           (1 << FD_OOB_BIT)
#define FD_ACCEPT_BIT    3
#define FD_ACCEPT        (1 << FD_ACCEPT_BIT)
#define FD_CONNECT_BIT   4
#define FD_CONNECT       (1 << FD_CONNECT_BIT)
#define FD_CLOSE_BIT     5
#define FD_CLOSE         (1 << FD_CLOSE_BIT)

ftp_scoket FPF_SockCreate(int nSocketPort, int nSocketType);
ftp_scoket FPF_Socket(int nSocketType);
bool FPF_SockBind(ftp_scoket s, int nSocketPort, const char* lpszSocketAddress);
bool FPF_SockConnect(ftp_scoket s, const char* lpszHostAddress, int nHostPort);
bool FPF_SockListen(ftp_scoket s, int backlog);
ftp_scoket FPF_SockAccept(ftp_scoket s);
int  FPF_SockReceive(ftp_scoket s, void* lpBuf, int nBufLen);
int  FPF_SockReceiveFrom(ftp_scoket s, void* lpBuf, int nBufLen, char* rSocketAddress, int* rSocketPort);
int  FPF_SockSend(ftp_scoket s, const void* lpBuf, int nBufLen);
int  FPF_SockSendTo(ftp_scoket s, const void* lpBuf, int nBufLen, const char* lpszHostAddress, int nHostPort);
bool FPF_SockShutDown(ftp_scoket s, int nHow);
#define FPF_SockClose(s) { close(s); s = INVALID_SOCKET; }

bool FPF_SockSelect(ftp_scoket s, int lEvent, int nMsTimeout);
bool FPF_SockGetPeerName(ftp_scoket s, char* rPeerAddress, int* rPeerPort);
bool FPF_SockGetSockName(ftp_scoket s, char* rSocketAddress, int* rSocketPort);
bool FPF_SockGetSockOpt(ftp_scoket s, int nLevel, int nOptionName, void* lpOptionValue, int* lpOptionLen);
bool FPF_SockSetSockOpt(ftp_scoket s, int nLevel, int nOptionName, const void* lpOptionValue, int nOptionLen);
bool FPF_SockIOCtl(ftp_scoket s, int iCommand, int* lpArgument);
int  FPF_SockGetLastError();

#endif /* __SOCKET_API_H__ */
